"""布尔属性的取值策略辅助工具。

根据 units 字段判断布尔值的表达方式，并提供统一的解析、展示与提示能力。
"""

from __future__ import annotations

from typing import Literal

BoolScheme = Literal["native", "numeric", "textual"]

_FULL_WIDTH_DIGITS = str.maketrans("０１", "01")


def _normalize_units(units: str | None) -> str:
    if not units:
        return ""
    return units.translate(_FULL_WIDTH_DIGITS).lower()


def detect_bool_scheme(units: str | None) -> BoolScheme:
    """根据 units 判断布尔值应采用的取值形式。
    
    只有当 units 中同时包含 "0" 和 "1" 时，才返回 "numeric"（生成 0 或 1），
    否则返回其他方案（生成 true 或 false）。
    """
    normalized = _normalize_units(units)
    if "true" in normalized or "false" in normalized:
        return "textual"
    # 只有当 0 和 1 同时出现在 units 中时，才使用 numeric 方案
    if "1" in normalized and "0" in normalized:
        return "numeric"
    return "native"


def bool_value_hint(scheme: BoolScheme) -> str:
    """返回用于错误提示的取值范围提示文本。"""
    if scheme == "numeric":
        return "0 或 1"
    if scheme == "textual":
        return "true 或 false"
    return "布尔值（true/false 或 1/0）"


def coerce_bool_value(value: object, scheme: BoolScheme):
    """根据指定的取值策略，将任意输入转换为合法布尔取值。

    :raises ValueError: 当输入不满足目标取值策略时抛出。
    """
    if isinstance(value, bool):
        if scheme == "numeric":
            return int(value)
        return value

    if isinstance(value, int):
        if scheme == "numeric" and value in (0, 1):
            return value
        if scheme != "numeric" and value in (0, 1):
            return bool(value)

    text = str(value).strip().lower()
    if not text:
        raise ValueError

    if scheme == "numeric":
        if text in {"0", "1"}:
            return int(text)
        raise ValueError

    if scheme == "textual":
        if text == "true":
            return True
        if text == "false":
            return False
        raise ValueError

    if text in {"true", "1", "yes", "on"}:
        return True
    if text in {"false", "0", "no", "off"}:
        return False
    raise ValueError


def format_bool_for_display(value: object, scheme: BoolScheme) -> str:
    """将布尔取值格式化为界面上展示所需的字符串。"""
    if scheme == "numeric":
        coerced = coerce_bool_value(value, "numeric")
        return str(coerced)

    # textual 与 native 模式在展示上均使用 true/false
    try:
        coerced = coerce_bool_value(value, scheme)
    except ValueError:
        coerced = value

    if isinstance(coerced, bool):
        return "true" if coerced else "false"
    if isinstance(coerced, int):
        return "true" if coerced else "false"

    return str(coerced).strip().lower() or "false"

